package com.fulu.netty.luban.flrpc.server.netty;

import com.fulu.netty.luban.flrpc.entity.ClassInfo;
import io.netty.channel.*;
import io.netty.util.concurrent.EventExecutorGroup;
import org.reflections.Reflections;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RpcServerHandler extends ChannelHandlerAdapter{

    private static ExecutorService executorService = Executors.newFixedThreadPool(100);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        executorService.submit(()->{
            try {
                if(msg instanceof ClassInfo){
                    ClassInfo classInfo = (ClassInfo) msg;
                    String className = getClassByInterface(classInfo);
                    Object o = Class.forName(className).newInstance();
                    Method method = o.getClass().getMethod(classInfo.getMethodName(), classInfo.getArgsClasses());
                    Object invoke = method.invoke(o, classInfo.getArgs());

                    ctx.channel().writeAndFlush(invoke);

                }else{
                    System.out.println("不是rpc");
                }
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    ctx.channel().closeFuture().sync();
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        });

    }

    private String getClassByInterface(ClassInfo classInfo) throws ClassNotFoundException {
        // 传过来的接口全限定名
        String className = classInfo.getClassName();
        // 接口所在目录
        String iPath = "com.fulu.netty.luban.flrpc.server.service";
        String cName = className.substring(className.lastIndexOf("."));
        Reflections reflections = new Reflections(iPath);
        Set<Class<?>> classes = (Set<Class<?>>) reflections.getSubTypesOf(Class.forName(iPath + cName));
        if(classes.size() == 0){
            System.out.println("没找到实现类");
            return null;
        }else if(classes.size() > 1){
            System.out.println("找到多个实现类");
            return null;
        }else{
            Class[] classes1 = classes.toArray(new Class[0]);
            return classes1[0].getName();
        }
    }
}
